1 module unit_threaded.randomized.random; 2 3 /** This type will generate a $(D Gen!T) for all passed $(D T...). 4 Every call to $(D genValues) will call $(D gen) of all $(D Gen) structs 5 present in $(D values). The member $(D values) can be passed to every 6 function accepting $(D T...). 7 */ 8 struct RndValueGen(T...) { 9 import std.meta : staticMap; 10 import std.random : Random; 11 12 /* $(D Values) is a collection of $(D Gen) types created through 13 $(D ParameterToGen) of passed $(T ...). 14 */ 15 static if (is(typeof(T[0]) == string[])) { 16 alias generators = T[1 .. $]; 17 string[] parameterNames = T[0]; 18 } else { 19 alias generators = T; 20 string[T.length] parameterNames; 21 } 22 23 alias Values = staticMap!(ParameterToGen, generators); 24 25 /// Ditto 26 Values values; 27 28 /* The constructor accepting the required random number generator. 29 Params: 30 rnd = The required random number generator. 31 */ 32 this(Random* rnd) @safe { 33 this.rnd = rnd; 34 } 35 36 this(ref Random rnd) { 37 this.rnd = &rnd; 38 } 39 40 /* The random number generator used to generate new value for all 41 $(D values). 42 */ 43 Random* rnd; 44 45 /** A call to this member function will call $(D gen) on all items in 46 $(D values) passing $(D the provided) random number generator 47 */ 48 void genValues() { 49 assert(rnd !is null); 50 foreach (ref it; this.values) { 51 it.gen(*this.rnd); 52 } 53 } 54 55 void toString(scope void delegate(const(char)[]) sink) { 56 import std.format : formattedWrite; 57 58 foreach (idx, ref it; values) { 59 formattedWrite(sink, "'%s' = %s ", parameterNames[idx], it); 60 } 61 } 62 } 63 64 /** A template that turns a $(D T) into a $(D Gen!T) unless $(D T) is 65 already a $(D Gen) or no $(D Gen) for given $(D T) is available. 66 */ 67 template ParameterToGen(T) { 68 import unit_threaded.randomized.gen : isGen, Gen; 69 70 static if (isGen!T) 71 alias ParameterToGen = T; 72 else static if (is(T : GenASCIIString!(S), S...)) 73 alias ParameterToGen = T; 74 else { 75 static assert(__traits(compiles, Gen!T), "ParameterToGen does not handle " ~ T.stringof); 76 alias ParameterToGen = Gen!T; 77 } 78 }